#!/usr/bin/env python
#-*- coding:utf-8 -*-
import os,sys
import multiprocessing
from multiprocessing.managers import BaseManager,BaseProxy
from wwpy.util.Logger import logger

class Process(object):
    
    def __init__(self,target=None,args=(),kwargs={}):
        self._process=multiprocessing.Process(target=target,args=args,kwargs=kwargs)
        
    def start(self):
        self._process.start()
        
    def join(self):
        self._process.join()
        
    def stop(self):
        self._process.terminate()

class ProcessPool(object):
    
    def __init__(self,processes=None,**kwargs):
        self._pool=multiprocessing.Pool(processes=processes,**kwargs)
        self._results=[]
        
    def put(self,func,*args,**kwargs):
        debug=kwargs.pop('debug',True)
        result=self._pool.apply_async(func,args=args,kwds=kwargs)
        if debug:
            name=func.__name__
            logger.info("Put job %s(%s,%s) into Queue." % (name,str(args),str(kwargs)))
        self._results.append(result)
        
    def wait(self):
        self._pool.close()
        self._pool.join()
        logger.info("All jobs all done.")
        
    def outs(self):
        logger.info("Output jobs's results.")
        for result in self._results:
            yield result.get()
            
    def map(self,func,iter):
        return self._pool.map(func,iter)
    
    def apply(self,func,*args,**kwargs):
        return self._pool.apply(func,args=args,kwds=kwargs)
    
class ObjectManager(BaseManager):
    pass

class SharedObject(object):
    
    def __init__(self,host='localhost',port=5000,auth_key='abcedf'):
        self._host=host
        self._port=port
        if self._host:
            self._manager=ObjectManager(address=(host,port),authkey=auth_key)
        else:
            self._manager=ObjectManager()
        
    def start(self):
        if self._host:
            s=self._manager.get_server()
            s.serve_forever()
        else:
            self._manager.start()
            
    def connect(self):
        if self._host:
            self._manager.connect()
        
    def get(self,name):
        ObjectManager.register(name)
        return getattr(self._manager,name)
    
    def set(self,name,func):
        ObjectManager.register(name,func)

class ObjectProxy(BaseProxy):
    _exposed_=('get','set')
    
    def get(self,name,*args,**kwargs):
        return self._callmethod(name,args=args,kwds=kwargs)
    
    def set(self,name,func):
        return self._callmethod(name,args=(func,))
    
